/*jadclipse*/// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) ansi radix(10) lradix(10) 
// Source File Name:   CAUtility.java

package com.edt.ichannel.utils;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Enumeration;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.X509CertificateStructure;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.util.encoders.Base64;

import ccit.security.bssp.base.CertParseBase;
import ccit.security.bssp.base.DigestBase;
import ccit.security.bssp.base.EcryptBase;
import ccit.security.bssp.base.SignBase;
import ccit.security.bssp.bean.CERT_INFO;
import ccit.security.bssp.bean.KeyPairInfo;
import ccit.security.bssp.bean.RSAKeyPair;
import ccit.security.bssp.ex.CCITSecurityException;
import ccit.security.bssp.ex.CrypException;
import ccit.security.bssp.sm2.Cryption;
import ccit.security.bssp.sm2.Randoms;
import ccit.security.bssp.sm2.SM2PrivateKeyDer;
import ccit.security.bssp.sm2.SM2PublicKeyDer;
import ccit.security.bssp.sm2.SMS4;
import ccit.security.bssp.sm2.Signature;
import ccit.security.bssp.util.Constants;
import ccit.security.bssp.util.MAC;
import ccit.security.bssp.util.MiscTools;
import ccit.security.bssp.util.ParseCertExtUtil;
import ccit.security.bssp.util.ParseCertUtil;
import ccit.security.bssp.util.Resource;

public class CAUtility {

	public CAUtility() {
	}

	public static CAUtility getInstance() {
		return new CAUtility();
	}

	public static RSAKeyPair generateRSAKeyPair(int modulusLen) throws CrypException {
		RSAKeyPair keypair = new RSAKeyPair();
		KeyPairGenerator keygen = null;
		try {
			keygen = KeyPairGenerator.getInstance("RSA");
			keygen.initialize(modulusLen);
			KeyPair keys = keygen.generateKeyPair();
			RSAPublicKey pubkey = (RSAPublicKey) keys.getPublic();
			RSAPrivateKey prikey = (RSAPrivateKey) keys.getPrivate();
			byte pubkeybyte[] = pubkey.getEncoded();
			byte prikeybyte[] = prikey.getEncoded();
			ByteArrayInputStream bIn = new ByteArrayInputStream(pubkeybyte);
			ASN1InputStream ais = new ASN1InputStream(bIn);
			org.bouncycastle.asn1.DERObject dobj = ais.readObject();
			DERSequence ass = (DERSequence) dobj;
			bIn.close();
			bIn = null;
			DERBitString pubOct = DERBitString.getInstance(ass.getObjectAt(1));
			bIn = new ByteArrayInputStream(prikeybyte);
			ASN1InputStream ais1 = new ASN1InputStream(bIn);
			org.bouncycastle.asn1.DERObject dobj1 = ais1.readObject();
			DERSequence ass1 = (DERSequence) dobj1;
			bIn.close();
			bIn = null;
			ASN1OctetString priOct = DEROctetString.getInstance(ass1.getObjectAt(2));
			keypair.setPrikeyDERString(priOct.getOctets());
			keypair.setPubkeyDERString(pubOct.getBytes());
			keypair.setPubkey(pubkey);
		} catch (InvalidParameterException ex) {
			throw new CrypException(-2147483642, (new StringBuilder("Don't Support Your Modulus Length!")).append(ex.getMessage()).toString());
		} catch (Exception exc) {
			throw new CrypException(-2147483647, (new StringBuilder("Operation Fail!")).append(exc.getMessage()).toString());
		}
		return keypair;
	}

	public static byte[] digest(byte src[], int algorithm) throws CrypException {
		if (src == null) {
			throw new CrypException(-2147450877, "Digest failed! Data to be digested cann't be null!");
		} else {
			byte digestdata[] = DigestBase.digest(src, algorithm);
			return digestdata;
		}
	}

	public static int verify(int type, byte publicKey[], byte indata[], byte sd[]) throws CrypException {
		if (publicKey == null)
			throw new CrypException(-2147483641, "Verify failed! Key cann't be null!");
		if (indata == null)
			throw new CrypException(-2147483641, "Verify failed! The data to be signed cann't be null!");
		if (sd == null)
			throw new CrypException(-2147483641, "Verify failed! The signed data cann't be null!");
		byte signaturepem[] = MiscTools.checkPEM(publicKey);
		if (signaturepem != null)
			publicKey = Base64.decode(signaturepem);
		byte signaturepem1[] = MiscTools.checkPEM(sd);
		if (signaturepem1 != null)
			sd = Base64.decode(signaturepem1);
		String Algorithms = "";
		if (type == 257)
			Algorithms = "MD2WITHRSA";
		else if (type == 258)
			Algorithms = "MD5WITHRSA";
		else if (type == 259)
			Algorithms = "SHA1WITHRSA";
		else if (type == 261)
			Algorithms = "SHA256WITHRSA";
		else
			throw new CrypException(-2147483643, "Don't Support Your Algorithms");
		int nFlag = SignBase.verify(Algorithms, publicKey, indata, sd);
		return nFlag;
	}

	public static int verifyWithCert(int type, byte cert[], byte indata[], byte sd[]) throws CrypException {
		if (cert == null)
			throw new CrypException(-2147483641, "Verify failed! Key cann't be null!");
		if (indata == null)
			throw new CrypException(-2147483641, "Verify failed! The data to be signed cann't be null!");
		if (sd == null)
			throw new CrypException(-2147483641, "Verify failed! The signed data cann't be null!");
		byte signaturepem[] = MiscTools.checkPEM(cert);
		if (signaturepem != null)
			cert = Base64.decode(signaturepem);
		byte signaturepem1[] = MiscTools.checkPEM(sd);
		if (signaturepem1 != null)
			sd = Base64.decode(signaturepem1);
		String Algorithms = "";
		if (type == 257)
			Algorithms = "MD2WITHRSA";
		else if (type == 258)
			Algorithms = "MD5WITHRSA";
		else if (type == 259)
			Algorithms = "SHA1WITHRSA";
		else if (type == 261)
			Algorithms = "SHA256WITHRSA";
		else
			throw new CrypException(-2147483643, "Don't Support Your Algorithms");
		int nFlag = SignBase.verifyWithCert(Algorithms, cert, indata, sd);
		return nFlag;
	}

	public static byte[] cryption(int type, byte key[], boolean bEncryption, byte inData[]) throws CrypException {
		if (key == null)
			throw new CrypException(-2147483641, "Operation failed! Key cann't be null!");
		if (inData == null)
			throw new CrypException(-2147483641, "Operation failed! The data to be encrypted or decrypted cann't be null!");
		byte signaturepem[];
		if (!bEncryption) {
			signaturepem = MiscTools.checkPEM(inData);
			if (signaturepem != null)
				inData = Base64.decode(signaturepem);
		}
		signaturepem = MiscTools.checkPEM(key);
		if (signaturepem != null)
			key = Base64.decode(signaturepem);
		String alg = "";
		if (type == 1)
			alg = "RSA/ECB/PKCS1Padding";
		else if (type == 2)
			alg = "RSA/ECB/NoPadding";
		else
			throw new CrypException(-2147483643, "Don't Support Your Algorithms");
		byte outdata[] = EcryptBase.crypto(alg, key, bEncryption, inData);
		return outdata;
	}

	public static byte[] symCrypto(int type, byte key[], boolean bEncrypto, byte inData[], byte parameter[]) throws CrypException {
		if (key == null)
			throw new CrypException(-2147483641, "Operation failed! Key cann't be null!");
		if (inData == null)
			throw new CrypException(-2147483641, "Operation failed! The data to be encrypted or decrypted cann't be null!");
		if (!bEncrypto) {
			byte signaturepem[] = MiscTools.checkPEM(inData);
			if (signaturepem != null)
				inData = Base64.decode(signaturepem);
		}
		byte outdata[] = (byte[]) null;
		String alg = "";
		try {
			if (type == 1282) {
				alg = "DESede/ECB/PKCS5Padding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1313) {
				alg = "DESede/ECB/NoPadding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1314) {
				alg = "DESede/CBC/PKCS5Padding";
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1315) {
				alg = "DESede/CBC/NoPadding";
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1281) {
				alg = "DES/ECB/PKCS5Padding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1297) {
				alg = "DES/ECB/NoPadding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1298) {
				alg = "DES/CBC/PKCS5Padding";
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1299) {
				alg = "DES/CBC/NoPadding";
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1285) {
				alg = "AES/ECB/PKCS5Padding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1361) {
				alg = "AES/ECB/NoPadding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1362) {
				alg = "AES/CBC/PKCS5Padding";
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1363) {
				alg = "AES/CBC/NoPadding";
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1283) {
				alg = "SDBI";
				outdata = EcryptBase.SymCryptoSDBI(alg, new String(key), bEncrypto, inData);
			} else if (type == 1284) {
				alg = "IDEA";
				outdata = EcryptBase.SymCryptoIDEA(alg, key, bEncrypto, inData);
			} else {
				throw new CrypException(-2147483643, "Don't Support Your Algorithms");
			}
		} catch (CrypException exc) {
			throw exc;
		} catch (Exception exc) {
			throw new CrypException(-2147483640, (new StringBuilder("Encryption or decryption failed!")).append(exc.getMessage()).toString());
		}
		return outdata;
	}

	public static int verifyCert(byte cert[], byte caCert[]) throws CrypException {
		if (cert == null)
			throw new CrypException(-2147483641, "Operation failed! certificat to be verified cann't be null!");
		if (caCert == null)
			throw new CrypException(-2147483641, "Operation failed! The verify cert cann't be null!");
		byte certpem[] = MiscTools.checkPEM(cert);
		if (certpem != null)
			cert = Base64.decode(certpem);
		byte rcertpem[] = MiscTools.checkPEM(caCert);
		if (rcertpem != null)
			caCert = Base64.decode(rcertpem);
		int nFlag = -1;
		CertParseBase certbase = new CertParseBase();
		nFlag = certbase.VerifyCert(cert, caCert);
		return nFlag;
	}

	public static boolean verifyCertificateByCrl(byte cert[], byte crl[]) throws CCITSecurityException {
		byte certpem[] = MiscTools.checkPEM(cert);
		if (certpem != null)
			cert = Base64.decode(certpem);
		byte crlpem[] = MiscTools.checkPEM(crl);
		if (crlpem != null)
			crl = Base64.decode(crlpem);
		boolean ret = CertParseBase.verifyCertificateByCrl(cert, crl);
		return ret;
	}

	public static CERT_INFO getCertInfo(byte cert[]) throws CrypException {
		if (cert == null)
			throw new CrypException(-2147483647, "Operation failed! certificat cann't be null!");
		byte signaturepem[] = MiscTools.checkPEM(cert);
		if (signaturepem != null)
			cert = Base64.decode(signaturepem);
		CERT_INFO certinfo = new CERT_INFO(cert);
		return certinfo;
	}

	public static byte[] getCertExtInfoString(byte cert[], String oid) throws CrypException {
		byte ret[] = (byte[]) null;
		if (cert == null)
			throw new CrypException(-2147483647, "Operation failed! certificat cann't be null!");
		byte signaturepem[] = MiscTools.checkPEM(cert);
		if (signaturepem != null)
			cert = Base64.decode(signaturepem);
		try {
			ParseCertUtil parseCertUtil = new ParseCertUtil(cert);
			org.bouncycastle.asn1.x509.X509Extensions x509Extensions = parseCertUtil.getExtensions();
			ParseCertExtUtil parseCertExtUtil = new ParseCertExtUtil(x509Extensions);
			ret = parseCertExtUtil.getExtSelfDefineExt(oid);
		} catch (Exception e) {
			throw new CrypException("Operation failed! Parse Certificate Extension error", e);
		}
		return ret;
	}

	public static byte[] mac(int algorithmType, String key, byte inData[]) throws CCITSecurityException {
		MAC mac = new MAC(algorithmType, key);
		mac.update(inData);
		byte ret[] = mac.doFinal();
		return ret;
	}

	public static byte[] base64Encode(byte inData[]) throws CrypException {
		return Base64.encode(inData);
	}

	public static byte[] base64Decode(byte inData[]) throws CrypException {
		return Base64.decode(inData);
	}

	public static void printHexString(byte b[]) {
		for (int i = 0; i < b.length; i++) {
			String hex = Integer.toHexString(b[i] & 255);
			if (hex.length() == 1)
				hex = (new StringBuilder(String.valueOf('0'))).append(hex).toString();
			System.out.println(hex.toUpperCase());
		}

	}

	public static byte[] ASymEncOrDec(int type, byte key[], boolean bEncryption, byte inData[]) throws CrypException {
		if (key == null)
			throw new CrypException(-2147483641, "Operation failed! Key cann't be null!");
		if (inData == null)
			throw new CrypException(-2147483641, "Operation failed! The data to be encrypted or decrypted cann't be null!");
		byte signaturepem[];
		if (!bEncryption) {
			signaturepem = MiscTools.checkPEM(inData);
			if (signaturepem != null)
				inData = Base64.decode(signaturepem);
		}
		signaturepem = MiscTools.checkPEM(key);
		if (signaturepem != null)
			key = Base64.decode(signaturepem);
		String alg = "";
		if (type == 1)
			alg = "RSA/ECB/PKCS1Padding";
		else if (type == 2)
			alg = "RSA/ECB/NoPadding";
		else
			throw new CrypException(-2147483643, "Don't Support Your Algorithms");
		byte outdata[] = EcryptBase.crypto(alg, key, bEncryption, inData);
		return outdata;
	}

	public static byte[] RsaSign(int type, byte privateKey[], byte indata[]) throws CrypException {
		if (privateKey == null)
			throw new CrypException(-2147450878, "Sign failed! Key cann't be null!");
		if (indata == null)
			throw new CrypException(-2147450878, "Sign failed! The data to be signed cann't be null!");
		byte signaturepem[] = MiscTools.checkPEM(privateKey);
		if (signaturepem != null)
			privateKey = Base64.decode(signaturepem);
		String Algorithms = "";
		if (type == 257)
			Algorithms = "MD2WITHRSA";
		else if (type == 258)
			Algorithms = "MD5WITHRSA";
		else if (type == 259)
			Algorithms = "SHA1WITHRSA";
		else if (type == 261)
			Algorithms = "SHA256WITHRSA";
		else
			throw new CrypException(-2147483643, "Algorithm unsupported!");
		byte signdata[] = SignBase.sign(Algorithms, privateKey, indata);
		return signdata;
	}

	public static byte[] EccSign(int type, byte privateKey[], byte indata[]) throws CrypException {
		if (privateKey == null)
			throw new CrypException(-2147483641, "Verify failed! privateKey cann't be null!");
		if (indata == null)
			throw new CrypException(-2147483641, "Verify failed! The data to be signed cann't be null!");
		byte date[] = (byte[]) null;
		Signature signature = new Signature();
		byte signaturepem[] = MiscTools.checkPEM(privateKey);
		if (signaturepem != null)
			privateKey = Base64.decode(signaturepem);
		try {
			if (type != 260)
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			date = signature.Sm2Sign(indata, Constants.UserID.getBytes("GB2312"), SM2PrivateKeyDer.sm2PrivateKeyDerDecode(privateKey), null);
		} catch (Exception e) {
			throw new CrypException(e.getMessage(), e);
		}
		return date;
	}

	public static int EccVerifySign(int type, byte publicKey[], byte indata[], byte sd[]) throws CrypException {
		if (publicKey == null)
			throw new CrypException(-2147483641, "Verify failed! publicKey cann't be null!");
		if (indata == null)
			throw new CrypException(-2147483641, "Verify failed! The data to be signed cann't be null!");
		if (sd == null)
			throw new CrypException(-2147483641, "Verify failed! The signed data cann't be null!");
		int ret = 1;
		Signature signature = new Signature();
		byte signaturepem[] = MiscTools.checkPEM(publicKey);
		if (signaturepem != null)
			publicKey = Base64.decode(signaturepem);
		byte signaturepem2[] = MiscTools.checkPEM(sd);
		if (signaturepem2 != null)
			sd = Base64.decode(signaturepem2);
		try {
			if (type != 260)
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			ret = signature.VerifySm2SignatureByPubKey(SM2PublicKeyDer.sm2PubkeyDerDecode(publicKey), sd, indata);
		} catch (Exception e) {
			throw new CrypException(e.getMessage(), e);
		}
		return ret;
	}

	public static int EccVerifySignByCert(int type, byte cert[], byte indata[], byte sd[]) throws CrypException {
		int ret = 1;
		if (cert == null)
			throw new CrypException(-2147483641, "Verify failed! Key cann't be null!");
		if (indata == null)
			throw new CrypException(-2147483641, "Verify failed! The data to be signed cann't be null!");
		if (sd == null)
			throw new CrypException(-2147483641, "Verify failed! The signed data cann't be null!");
		byte signaturepem[] = MiscTools.checkPEM(cert);
		if (signaturepem != null)
			cert = Base64.decode(signaturepem);
		byte signaturepem1[] = MiscTools.checkPEM(sd);
		if (signaturepem1 != null)
			sd = Base64.decode(signaturepem1);
		try {
			Signature signature = new Signature();
			CERT_INFO certINFO = new CERT_INFO(cert);
			if (type != 260)
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			ret = signature.VerifySm2SignatureByPubKey(SM2PublicKeyDer.sm2PubkeyDerDecode(certINFO.getPublicKey()), sd, indata);
		} catch (Exception e) {
			throw new CrypException(e.getMessage(), e);
		}
		return ret;
	}

	public static byte[] SymEncOrDec(int type, byte key[], boolean bEncrypto, byte inData[], byte parameter[]) throws CrypException {
		if (key == null)
			throw new CrypException(-2147483641, "Operation failed! Key cann't be null!");
		if (inData == null)
			throw new CrypException(-2147483641, "Operation failed! The data to be encrypted or decrypted cann't be null!");
		if (!bEncrypto) {
			byte signaturepem[] = MiscTools.checkPEM(inData);
			if (signaturepem != null)
				inData = Base64.decode(signaturepem);
		}
		byte outdata[] = (byte[]) null;
		String alg = "";
		try {
			if (type == 1282) {
				alg = "DESede/ECB/PKCS5Padding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1313) {
				alg = "DESede/ECB/NoPadding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1314) {
				alg = "DESede/CBC/PKCS5Padding";
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1315) {
				alg = "DESede/CBC/NoPadding";
				outdata = EcryptBase.symCrypto3DES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1281) {
				alg = "DES/ECB/PKCS5Padding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1297) {
				alg = "DES/ECB/NoPadding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1298) {
				alg = "DES/CBC/PKCS5Padding";
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1299) {
				alg = "DES/CBC/NoPadding";
				outdata = EcryptBase.symCryptoDES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1285) {
				alg = "AES/ECB/PKCS5Padding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1361) {
				alg = "AES/ECB/NoPadding";
				parameter = (byte[]) null;
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1362) {
				alg = "AES/CBC/PKCS5Padding";
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1363) {
				alg = "AES/CBC/NoPadding";
				outdata = EcryptBase.symCryptoAES(alg, key, bEncrypto, inData, parameter);
			} else if (type == 1283) {
				alg = "SDBI";
				outdata = EcryptBase.SymCryptoSDBI(alg, new String(key), bEncrypto, inData);
			} else if (type == 1284) {
				alg = "IDEA";
				outdata = EcryptBase.SymCryptoIDEA(alg, key, bEncrypto, inData);
			} else {
				throw new CrypException(-2147483643, "Don't Support Your Algorithms");
			}
		} catch (CrypException exc) {
			throw exc;
		} catch (Exception exc) {
			throw new CrypException(-2147483640, (new StringBuilder("Encryption or decryption failed!")).append(exc.getMessage()).toString());
		}
		return outdata;
	}

	public static KeyPairInfo genEccKeyPair() {
		KeyPairInfo info = null;
		byte bytKeyPairRand[] = Randoms.getRandom();
		byte pubkey[] = ccit.security.bssp.sm2.KeyPair.GenSM2KeyPair(bytKeyPairRand);
		byte prikey[] = ccit.security.bssp.sm2.KeyPair.GetPrivateKey();
		String prikeyString = new String(Base64.encode(SM2PrivateKeyDer.sm2PrivateKeyDerEncode(pubkey, prikey)));
		String pubkeyString = new String(Base64.encode(SM2PublicKeyDer.sm2PubKeyDerEncode(pubkey)));
		if (prikeyString != null && !"".equals(prikeyString) && pubkeyString != null && !"".equals(pubkeyString)) {
			info = new KeyPairInfo();
			info.setPrivateKey(prikeyString);
			info.setPublicKey(pubkeyString);
		}
		return info;
	}

	public static byte[] SMS4_ECB(boolean type, byte keyData[], byte indata[]) throws Exception {
		if (keyData == null)
			throw new Exception("keyData is null");
		if (indata == null)
			throw new Exception("indata is null");
		SMS4 sm;
		byte outData[];
		if (type) {
			sm = new SMS4();
			outData = (byte[]) null;
			try {
				outData = sm.sms4encodeecbpkcs5padding(indata, keyData);
			} catch (Exception e) {
				e.printStackTrace();
				throw e;
			}
			return Base64.encode(outData);
		}
		sm = new SMS4();
		outData = (byte[]) null;
		try {
			outData = sm.sms4decodeecbpkcs5padding(Base64.decode(indata), keyData);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return outData;
	}

	public static String SM3Hash(String indata) throws Exception {
		if (isEmpty(indata)) {
			throw new Exception("indata is null");
		} else {
			byte hashdate[] = ccit.security.bssp.sm2.SM3Hash.GetHashValue(indata.getBytes());
			return new String(Base64.encode(hashdate));
		}
	}

	public static byte[] RsaSignByP12(int type, byte indata[]) throws CryptoException {
		byte signtedate[] = (byte[]) null;
		try {
			if (indata == null)
				throw new CryptoException("indata is null");
			String prikey = " ";
			String filepath = Resource.getValue(Constants.P12_CERT);
			String p12pincode = Resource.getValue(Constants.P12_PINCODE);
			KeyStore ks = KeyStore.getInstance("PKCS12");
			FileInputStream fis = new FileInputStream(filepath);
			char nPassword[] = (char[]) null;
			if (p12pincode == null || p12pincode.trim().equals(""))
				nPassword = (char[]) null;
			else
				nPassword = p12pincode.toCharArray();
			ks.load(fis, nPassword);
			fis.close();
			Enumeration enum1 = ks.aliases();
			String keyAlias = null;
			if (enum1.hasMoreElements())
				keyAlias = (String) enum1.nextElement();
			PrivateKey privatekey = (PrivateKey) ks.getKey(keyAlias, nPassword);
			prikey = new String(Base64.encode(privatekey.getEncoded()));
			String Algorithms = "";
			if (type == 257)
				Algorithms = "MD2WITHRSA";
			else if (type == 258)
				Algorithms = "MD5WITHRSA";
			else if (type == 259)
				Algorithms = "SHA1WITHRSA";
			else if (type == 261)
				Algorithms = "SHA256WITHRSA";
			else
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			signtedate = RsaSign(type, removePrikeyHead(prikey).getBytes(), indata);
			if (signtedate == null)
				throw new CryptoException("signtedate is null");
		} catch (CrypException e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		}
		return signtedate;
	}

	private static String removePrikeyHead(String prikey) {
		try {
			ByteArrayInputStream bIn = new ByteArrayInputStream(Base64.decode(prikey));
			ASN1InputStream ais1 = new ASN1InputStream(bIn);
			org.bouncycastle.asn1.DERObject dobj1 = ais1.readObject();
			DERSequence ass1 = (DERSequence) dobj1;
			bIn.close();
			bIn = null;
			ASN1OctetString priOct = DEROctetString.getInstance(ass1.getObjectAt(2));
			prikey = new String(Base64.encode(priOct.getOctets()));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return prikey;
	}

	public static String SM2EncOrDec(boolean type, String keyData, String indata) throws Exception {
		if (isEmpty(keyData))
			throw new Exception("keyData is null");
		if (isEmpty(indata))
			throw new Exception("indata is null");
		byte encdate[];
		try {
			encdate = (byte[]) null;
			if (type) {
				byte bytCryptRand[] = Randoms.getRandom();
				encdate = Cryption.SM2Encrypt(indata.getBytes(), SM2PublicKeyDer.sm2PubkeyDerDecode(Base64.decode(keyData)), bytCryptRand);
				return new String(Base64.encode(encdate));
			}
		} catch (Exception e) {
			throw e;
		}
		encdate = Cryption.SM2Decrypt(Base64.decode(indata.getBytes()), SM2PrivateKeyDer.sm2PrivateKeyDerDecode(Base64.decode(keyData)));
		return new String(encdate);
	}

	public static boolean isCert(String cert) {
		boolean flag = false;
		try {
			if (isEmpty(cert))
				throw new Exception("cert is null");
			ByteArrayInputStream bIn1 = new ByteArrayInputStream(Base64.decode(cert));
			ASN1InputStream ais1 = new ASN1InputStream(bIn1);
			org.bouncycastle.asn1.DERObject dobj1 = ais1.readObject();
			ASN1Sequence ass1 = (ASN1Sequence) dobj1;
			ais1.close();
			bIn1.close();
			bIn1 = null;
			X509CertificateStructure x509cert1 = new X509CertificateStructure(ass1);
			if (x509cert1 != null)
				flag = true;
		} catch (Exception e) {
			flag = false;
		}
		return flag;
	}

	private static boolean isEmpty(String data) {
		return data == null || "".equals(data.trim());
	}

	public static byte[] RsaSignByP12Cert(int type, byte indata[], byte P12cert[], String pincode) throws CryptoException {
		byte signtedate[] = (byte[]) null;
		try {
			if (indata == null)
				throw new CryptoException("indata is null");
			if (P12cert == null)
				throw new CryptoException("P12cert is null");
			String prikey = " ";
			byte signaturepem[] = MiscTools.checkPEM(P12cert);
			if (signaturepem != null)
				P12cert = Base64.decode(signaturepem);
			KeyStore ks = KeyStore.getInstance("PKCS12");
			InputStream fos = new ByteArrayInputStream(P12cert);
			char nPassword[] = (char[]) null;
			if (pincode == null || pincode.trim().equals(""))
				nPassword = (char[]) null;
			else
				nPassword = pincode.toCharArray();
			ks.load(fos, nPassword);
			fos.close();
			Enumeration enum1 = ks.aliases();
			String keyAlias = null;
			if (enum1.hasMoreElements())
				keyAlias = (String) enum1.nextElement();
			PrivateKey privatekey = (PrivateKey) ks.getKey(keyAlias, nPassword);
			prikey = new String(Base64.encode(privatekey.getEncoded()));
			String Algorithms = "";
			if (type == 257)
				Algorithms = "MD2WITHRSA";
			else if (type == 258)
				Algorithms = "MD5WITHRSA";
			else if (type == 259)
				Algorithms = "SHA1WITHRSA";
			else if (type == 261)
				Algorithms = "SHA256WITHRSA";
			else
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			signtedate = RsaSign(type, removePrikeyHead(prikey).getBytes(), indata);
			if (signtedate == null)
				throw new CryptoException("signtedate is null");
		} catch (CrypException e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		}
		return signtedate;
	}

	/**
	 * @author wangshengyao
	 * @date 2017年03月09日
	 * @param type
	 * @param indata
	 * @param merNo
	 * @return
	 * @throws CryptoException
	 */
	public static byte[] RsaSignByP12Conf(int type, byte indata[], String merNo) throws CryptoException {
		byte signtedate[] = null;
		try {
			if (indata == null)
				throw new CryptoException("indata is null");
			String prikey = " ";
			// 如果用户传入商户号码，根据商户号码查询
			String filepath = Resource.getValue(merNo != null ? merNo + "_" + Constants.P12_CERT : Constants.P12_CERT);
			String p12pincode = Resource.getValue(merNo != null ? merNo + "_" + Constants.P12_PINCODE : Constants.P12_PINCODE);

			KeyStore ks = KeyStore.getInstance("PKCS12");
			// 相对class路径配置 301100710007142_p12cert=/cerDir/301100710007142.pfx
			FileInputStream fis = new FileInputStream(CAUtility.class.getResource(filepath).getFile());
			System.out.println(fis.toString());
			// 绝对路径配置
			// FileInputStream fis = new FileInputStream(filepath);

			char nPassword[] = null;
			if (p12pincode == null || p12pincode.trim().equals(""))
				nPassword = null;
			else
				nPassword = p12pincode.toCharArray();
			ks.load(fis, nPassword);
			fis.close();
			Enumeration enum1 = ks.aliases();
			String keyAlias = null;
			if (enum1.hasMoreElements())
				keyAlias = (String) enum1.nextElement();
			PrivateKey privatekey = (PrivateKey) ks.getKey(keyAlias, nPassword);
			prikey = new String(Base64.encode(privatekey.getEncoded()));
			String Algorithms = "";
			if (type == 257)
				Algorithms = "MD2WITHRSA";
			else if (type == 258)
				Algorithms = "MD5WITHRSA";
			else if (type == 259)
				Algorithms = "SHA1WITHRSA";
			else if (type == 261)
				Algorithms = "SHA256WITHRSA";
			else
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			signtedate = RsaSign(type, removePrikeyHead(prikey).getBytes(), indata);
			if (signtedate == null)
				throw new CryptoException("signtedate is null");
		} catch (CrypException e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		}
		return signtedate;
	}

	/**
	 * @author zhangyanping
	 * @date 2018年03月08日
	 * @param type
	 * @param indata
	 * @param merNo
	 * @param merCer
	 * @param cerPinCode
	 * @param 说明
	 *            ：根据filePath读取商户证书
	 * @return
	 * @throws CryptoException
	 */
	public static byte[] RsaSignByP12Conf(int type, byte indata[], String merNo, String merCer, String cerPinCode) throws CryptoException {
		byte signtedate[] = null;
		try {
			if (indata == null)
				throw new CryptoException("indata is null");
			String prikey = " ";
			// 如果用户传入商户号码，根据商户号码查询

			// String filepath = Resource.getValue(merNo != null ? merNo + "_" +
			// Constants.P12_CERT : Constants.P12_CERT);
			// String p12pincode = Resource.getValue(merNo != null ? merNo + "_"
			// + Constants.P12_PINCODE : Constants.P12_PINCODE);
			String filepath = merNo != null ? merNo + "_" + merCer : merCer;
			String p12pincode = merNo != null ? merNo + "_" + cerPinCode : cerPinCode;

			KeyStore ks = KeyStore.getInstance("PKCS12");
			// 相对class路径配置 301100710007142_p12cert=/cerDir/301100710007142.pfx
			FileInputStream fis = new FileInputStream(CAUtility.class.getResource(filepath).getFile());
			System.out.println(fis.toString());
			// 绝对路径配置
			// FileInputStream fis = new FileInputStream(filepath);

			char nPassword[] = null;
			if (p12pincode == null || p12pincode.trim().equals(""))
				nPassword = null;
			else
				nPassword = p12pincode.toCharArray();
			ks.load(fis, nPassword);
			fis.close();
			Enumeration enum1 = ks.aliases();
			String keyAlias = null;
			if (enum1.hasMoreElements())
				keyAlias = (String) enum1.nextElement();
			PrivateKey privatekey = (PrivateKey) ks.getKey(keyAlias, nPassword);
			prikey = new String(Base64.encode(privatekey.getEncoded()));
			String Algorithms = "";
			if (type == 257)
				Algorithms = "MD2WITHRSA";
			else if (type == 258)
				Algorithms = "MD5WITHRSA";
			else if (type == 259)
				Algorithms = "SHA1WITHRSA";
			else if (type == 261)
				Algorithms = "SHA256WITHRSA";
			else
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			signtedate = RsaSign(type, removePrikeyHead(prikey).getBytes(), indata);
			if (signtedate == null)
				throw new CryptoException("signtedate is null");
		} catch (CrypException e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		}
		return signtedate;
	}

	/**
	 * @author zhangyanping
	 * @date 2018年03月08日
	 * @param type
	 * @param indata
	 * @param merCer 证书
	 * @param cerPinCode 证书密码
	 * @param 说明：读取配置文件中的配置。
	 * @return
	 * @throws CryptoException
	 */
	public static byte[] RsaSignByP12(int type, byte indata[], String merCer, String cerPinCode) throws CryptoException {
		byte signtedate[] = (byte[]) null;
		try {
			if (indata == null)
				throw new CryptoException("indata is null");
			String prikey = " ";
			// String filepath = Resource.getValue(Constants.P12_CERT);
			// String p12pincode = Resource.getValue(Constants.P12_PINCODE);
			KeyStore ks = KeyStore.getInstance("PKCS12");
			FileInputStream fis = new FileInputStream(merCer);
			char nPassword[] = (char[]) null;
			if (cerPinCode == null || cerPinCode.trim().equals(""))
				nPassword = (char[]) null;
			else
				nPassword = cerPinCode.toCharArray();
			ks.load(fis, nPassword);
			fis.close();
			Enumeration enum1 = ks.aliases();
			String keyAlias = null;
			if (enum1.hasMoreElements())
				keyAlias = (String) enum1.nextElement();
			PrivateKey privatekey = (PrivateKey) ks.getKey(keyAlias, nPassword);
			prikey = new String(Base64.encode(privatekey.getEncoded()));
			String Algorithms = "";
			if (type == 257)
				Algorithms = "MD2WITHRSA";
			else if (type == 258)
				Algorithms = "MD5WITHRSA";
			else if (type == 259)
				Algorithms = "SHA1WITHRSA";
			else if (type == 261)
				Algorithms = "SHA256WITHRSA";
			else
				throw new CrypException(-2147483643, "Algorithm unsupported!");
			signtedate = RsaSign(type, removePrikeyHead(prikey).getBytes(), indata);
			if (signtedate == null)
				throw new CryptoException("signtedate is null");
		} catch (CrypException e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
			throw new CryptoException(e.getMessage());
		}
		return signtedate;
	}
}
